package config

import (
	"fmt"
	"os"
	"path/filepath"
	"regexp"
	"strings"

	"gopkg.in/yaml.v3"
	"x-admin-generator/internal/types"
)

// 配置常量
const (
	ConfigFile = "config/config.yaml" // 生成器配置文件
)

// 全局配置变量
var generatorConfig *types.GeneratorConfig

// Load 加载生成器配置
func Load() error {
	data, err := os.ReadFile(ConfigFile)
	if err != nil {
		return fmt.Errorf("读取配置文件失败: %w", err)
	}

	generatorConfig = &types.GeneratorConfig{}
	if err := yaml.Unmarshal(data, generatorConfig); err != nil {
		return fmt.Errorf("解析配置文件失败: %w", err)
	}

	return nil
}

// GetConfig 获取配置
func GetConfig() *types.GeneratorConfig {
	return generatorConfig
}

// GetConfigPath 获取配置路径
func GetConfigPath(relativePath string) string {
	return filepath.Join(generatorConfig.Paths.ModelsConfig, relativePath)
}

// GetTempDir 获取临时目录
func GetTempDir() string {
	return generatorConfig.Paths.TempDir
}

// LoadModelConfig 加载模型配置
func LoadModelConfig(configPath string) (*types.ModelConfig, error) {
	data, err := os.ReadFile(configPath)
	if err != nil {
		return nil, fmt.Errorf("读取配置文件失败: %w", err)
	}

	var config types.ModelConfig
	if err := yaml.Unmarshal(data, &config); err != nil {
		return nil, fmt.Errorf("解析配置文件失败: %w", err)
	}

	return &config, nil
}

// SaveModelConfig 保存模型配置
func SaveModelConfig(configPath string, config *types.ModelConfig) error {
	// 确保目录存在
	if err := os.MkdirAll(filepath.Dir(configPath), 0755); err != nil {
		return fmt.Errorf("创建配置目录失败: %w", err)
	}

	// 序列化为YAML
	data, err := yaml.Marshal(config)
	if err != nil {
		return fmt.Errorf("序列化配置失败: %w", err)
	}

	// 写入文件
	if err := os.WriteFile(configPath, data, 0644); err != nil {
		return fmt.Errorf("写入配置文件失败: %w", err)
	}

	return nil
}

// GetModulePath 从 go.mod 文件中获取模块路径
func GetModulePath() string {
	// 配置中的项目根目录
	projectRoot := generatorConfig.Paths.ProjectRoot

	// 首先尝试读取 backend/go.mod
	backendGoMod := filepath.Join(projectRoot, "backend", "go.mod")
	content, err := os.ReadFile(backendGoMod)
	if err != nil {
		// 如果找不到，尝试读取项目根目录的 go.mod
		rootGoMod := filepath.Join(projectRoot, "go.mod")
		content, err = os.ReadFile(rootGoMod)
		if err != nil {
			// 使用配置中的默认值
			return generatorConfig.Generation.PackagePrefix
		}
	}

	// 使用正则表达式匹配模块路径
	re := regexp.MustCompile(`module\s+([\w\-\.\/]+)`)
	matches := re.FindSubmatch(content)
	if len(matches) < 2 {
		// 使用配置中的默认值
		return generatorConfig.Generation.PackagePrefix
	}

	return string(matches[1])
}

// GetDatabaseConfig 获取数据库配置
func GetDatabaseConfig() *types.DatabaseConfig {
	// 尝试从项目配置文件读取数据库配置
	for _, configPath := range generatorConfig.Database.ConfigPaths {
		if _, err := os.Stat(configPath); err == nil {
			if config := loadDatabaseConfigFromFile(configPath); config != nil {
				return config
			}
		}
	}

	// 使用默认配置
	return &types.DatabaseConfig{
		Driver:   generatorConfig.Database.Driver,
		Host:     generatorConfig.Database.Host,
		Port:     generatorConfig.Database.Port,
		Username: generatorConfig.Database.Username,
		Password: generatorConfig.Database.Password,
		Database: generatorConfig.Database.Database,
		Charset:  generatorConfig.Database.Charset,
		SSLMode:  generatorConfig.Database.SSLMode,
	}
}

// loadDatabaseConfigFromFile 从配置文件读取数据库配置
func loadDatabaseConfigFromFile(configPath string) *types.DatabaseConfig {
	fmt.Printf("📁 尝试读取配置文件: %s\n", configPath)

	data, err := os.ReadFile(configPath)
	if err != nil {
		fmt.Printf("⚠️  读取配置文件失败: %v\n", err)
		return nil
	}

	var appConfig types.AppConfig
	if err := yaml.Unmarshal(data, &appConfig); err != nil {
		fmt.Printf("⚠️  解析配置文件失败: %v\n", err)
		return nil
	}

	// 验证数据库配置是否完整
	dbConfig := &appConfig.Database
	if dbConfig.Host == "" || dbConfig.Username == "" || dbConfig.Database == "" {
		fmt.Printf("⚠️  配置文件中的数据库配置不完整\n")
		return nil
	}

	fmt.Printf("✅ 成功读取数据库配置: %s@%s:%d/%s\n",
		dbConfig.Username, dbConfig.Host, dbConfig.Port, dbConfig.Database)
	return dbConfig
}

// ToCamelCase 转换为驼峰命名
func ToCamelCase(s string) string {
	parts := strings.Split(s, "_")
	var result strings.Builder
	for i, part := range parts {
		if i == 0 {
			result.WriteString(strings.ToLower(part))
		} else {
			result.WriteString(strings.Title(part))
		}
	}
	return result.String()
}

// ToSnakeCase 转换为下划线命名
func ToSnakeCase(s string) string {
	var result strings.Builder
	for i, r := range s {
		if i > 0 && r >= 'A' && r <= 'Z' {
			result.WriteRune('_')
		}
		result.WriteRune(r)
	}
	return strings.ToLower(result.String())
}